from dao.item import ItemDao
from dao.category import CategoryDao
from model.picture import Picture
from bson.dbref import DBRef

class PictureDao(ItemDao):
    def __init__(self):
        ItemDao.__init__(self, Picture)
        
        self.collection = 'pictures'
        
    def insert(self, picture):
        """Save the object to collection
        Arguments:
            picture --- The Address Model object
        """
        if isinstance(picture, Picture):
            # Insert except ID field, because ID will be automatically generated
            _dict = {}
            _dict['name'] = picture.name;
            _dict['description'] = picture.description;
            _dict['fname'] = picture.fname;
            _dict['order'] = picture.order;
            _dict['created'] = picture.created;
            
            _dict['category'] = DBRef('categories', picture.category._id)
            collection = self.items[picture.category.name][0]
            _dict['item'] = DBRef( collection, picture.item._id );
            
            return self.db.insert(self.collection, _dict)
        
        return None
    
    
    def save(self, model):
        """Updates an existing document or inserts a new document, depending on its document parameter.
        Arguments:
            model --- The Model object with id if model is a dict type, the dbref field must be DBRef type
        Return:
            The '_id' value of to_save or [None] if manipulate is False and to_save has no _id field.
        """
        # The ID field must exist
        if isinstance(model, dict):
            return self.db.save(self.collection, model)
        else:            
    
            # The ID field must exist
            collection = self.items[model.category.name][0]
            
            # The __dict__ will modify object itself
            _dict = model.__dict__
            if _dict is not None:
                _dict['category'] = DBRef('categories', model.category._id)
                _dict['item'] = DBRef(collection, model.item._id );
                
                return self.db.save(self.collection, _dict)
            else:
                return None
    
    def find_one(self, query):
        """
        Arguments:
            query --- The dict type
        Return:
            Raises TypeError if any of the arguments are of improper type. 
            Returns an instance of Cursor corresponding to this query.
        """
        _dict = self.db.find_one(self.collection, query)
        
        if _dict is not None:
            category_dbref = _dict['category']
            item_dbref = _dict['item']
            
            category_dao = CategoryDao()
            _dict['category'] = category_dao.find_one({'_id':category_dbref.id})
            category_name = _dict['category'].name
            ItemDaoClass = self.items[category_name][1]
            item_dao = ItemDaoClass()
            _dict['item'] = item_dao.find_one({'_id':item_dbref.id})
            
            return self.ModelClass(_dict)
        else:
            return None
        
    def find(self, query={}):
        """
        Arguments:
            query --- The dict type
        Return:
            Raises TypeError if any of the arguments are of improper type. 
            Returns an instance of Cursor corresponding to this query.
        """
        cursor = self.db.find(self.collection, query=query)
        rets = []
        for _dict in cursor:
            category_dbref = _dict['category']
            item_dbref = _dict['item']
            
            category_dao = CategoryDao()
            _dict['category'] = category_dao.find_one({'_id':category_dbref.id})
            
            category_name = _dict['category'].name
            ItemDaoClass = self.items[category_name][1]
            item_dao = ItemDaoClass()
            _dict['item'] = item_dao.find_one({'_id':item_dbref.id})
            
            rets.append(self.ModelClass(_dict))
        return rets
    
    """
    def __init__(self):
        #alchemy = SQLAlchemy(app)
        self.session = db.session#alchemy.session

    def delete(self, *args, **kwargs):
        ''' filter and get the first
        Arguments:
            kwargs -- dict type
        '''    
        self.session.query(Picture).filter_by(**kwargs).delete()
        self.session.flush()
    
    def add_to_db(self, picture, item):
        item.pictures.append(picture)
        self.session.add(picture)
        self.session.commit()
        
    def remove_from_db(self, picture):
        self.session.delete(picture)
        self.session.commit()

    def update_picture(self, _id, name, path, description=None, _type=0):
        _picture = self.session.query(Picture).get(_id)
        _picture.name = name
        _picture.description = description
        _picture.path = path
        _picture.type = _type
        
        self.session.commit()
    
    def all(self, order_by):
        '''Get all rows
        '''
        return self.session.query(Picture).order_by(order_by)
    
    def filter(self, *criterion):
        '''
        Arguments:
            criterion -- list
        '''
        return self.session.query(Picture).filter(criterion).first()

    
    def filter_by(self, *args, **kwargs):
        '''
        Arguments:
            kwargs -- dict type
        '''    
        return self.session.query(Picture).filter_by(**kwargs)
    
    def filter_first(self, *args, **kwargs):
        ''' filter and get the first
        Arguments:
            kwargs -- dict type
        '''    
        return self.session.query(Picture).filter_by(**kwargs).first()

    """
